package dataBase;

/*
 * Created on 14/01/2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */


/**
 * @author Sbyte
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;

public class ConnectionPool {

	/**********Atributos de conexao *******************/
	
	private static final String driver = "com.mysql.jdbc.Driver";

	private static final String url = "jdbc:mysql://localhost:3306/webapsee?autoReconnect=true"; 
	private static final String usuario = "root"; 
	private static final String senha = "";

	/****************************/
	
	private int maxcon;
	private static Vector connections;
	private static int checkedout;
	private static ConnectionPool p;
	private final long TIMEOUT = 1000;
	private final int  NUMBER_TRIES = 5;
	private final long TIMEOUT_TRIES = TIMEOUT/NUMBER_TRIES;
	
	/**
	 * Contrutor da ConnectionPool
	 * @param driver
	 * @param url
	 * @param usuario
	 * @param senha
	 * @param maxcon
	 */
	private ConnectionPool(
		String driver,
		String url,
		String usuario,
		String senha,
		int maxcon) {
		connections = new Vector();
/*		this.driver = driver;
		this.url = url;
		this.usuario = usuario;
		this.senha = senha;
*/		this.maxcon = maxcon;
		checkedout = 0;
	}
	
	
	/****** Construtor vazio, usado por outras classes
	 *  	quando necessario pegar os atributos de conexao */
	public ConnectionPool()
	{
	}
	/************/
	
	/**
	 *  Servi�o que pega as conex�es de banco de dados
	 * @return Connection
	 */
	public synchronized java.sql.Connection getConnection() {
		Connection con = null;
		long startTime  = (new Date()).getTime();

		//verifica se vetor de conex�o possui conex�o
		if (connections.size() > 0) {
			//pega a primeira conex�o no vector
			con = (Connection) connections.firstElement();
			connections.removeElementAt(0);
			try {
				if (con.isClosed()) {
					//tenta novamente
					con = getConnection();
				}
			} catch (Exception e) {
				//novas tentativas com timeout
				while((con = getConnection()) == null) {
					try{
						wait(TIMEOUT_TRIES);
					} catch(InterruptedException ie){}
					
					if((new Date().getTime() - startTime) >= TIMEOUT){
						break;
					}
				}
				
			}
		}
		//verifica sen�o tem conex�o aberta
		else if (maxcon == 0 || checkedout < maxcon) {
			con = newConnection();
		}
		if (con != null)
			checkedout++;
		return con;
	}

	/**
	 * Servi�o que cria as conex�es
	 * @return Connection
	 */
	public synchronized java.sql.Connection newConnection() {
		Connection con = null;
		try {
			//carregar o driver
			Class.forName(driver).newInstance();

			con = DriverManager.getConnection(url,usuario,senha);
			
			//con.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
				
		} catch (Exception e) {
			e.printStackTrace();
			con = null;
		} finally {
			return con;
		}

	}

	/**
	 * Servi�o que libera a conex�o para futuro uso
	 * @param con
	 */
	public synchronized void freeConnection(Connection con) {
		//coloca a conex�o ao fim do vetor
		connections.addElement(con);
		checkedout--;
		notifyAll();
	}
	

	/**
	 * Servi�o que fecha todas as conex�es ao final da aplica��o.
	 * Obs: antes do objeto singleton ser recolhido pelo GC
	 *
	 */
	public synchronized void release() {
		Enumeration all = connections.elements();
		while (all.hasMoreElements()) {
			Connection con = (Connection) all.nextElement();
			try {
				con.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		connections.removeAllElements();
	}

	/**
	 * Servi�o de interface de acesso ao pool
	 * @return
	 */
/*	public static synchronized ConnectionPool getInstance() {
		if (p == null) {

//			USER_JDBC = sgo
//			PWD_JDBC = led
	
			p =	new ConnectionPool(Parametros.getParametro("DRIVER_JDBC"),
					"jdbc:mysql://localhost:3306/test?autoReconnect=true",
					Parametros.getParametro("USER_JDBC"),
					Parametros.getParametro("PWD_JDBC"),
					10);
			
		}
		return p;

	}
*/
	public static synchronized ConnectionPool getInstance() {
		if (p == null) {
/*
			USER_JDBC = sgo
			PWD_JDBC = led
*/	
			p =	new ConnectionPool(driver, url,	usuario, senha,
									10);
			
		}
		return p;

	}

	public static String getDriver() {
		return driver;
	}

	public static String getSenha() {
		return senha;
	}

	public static String getUrl() {
		return url;
	}

	public static String getUsuario() {
		return usuario;
	}
	
	
}
